import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import Qt
from gui import visu_gui
from core import processing as proc, pySpec as obj
from parsers import MzXML_Parser, lxml_target
import re
from controller import ControllerDialog as dial

class Parsing_thread(QtCore.QThread):
	"""thread for visualisation, parsing"""
	
	def __init__(self, files, lxml, time_cycle, chrom_model, spectr_model, parent=None):
		"""Constructor thread, handles the two models"""
		
		QtCore.QThread.__init__(self, parent)
		self.files =files
		self.chrom_model = chrom_model
		self.spectr_model = spectr_model
		self.parent =parent
		self.time_cycle =time_cycle
		self.lxml =lxml
	
	def emission(self, value):
		self.emit(QtCore.SIGNAL("update_pb"), value)
		
	def run(self):
		"""Have to redefine this function"""
		for item in self.files:
			if self.lxml:
				parser= lxml_target.lxml_parser(item)
			else:
				parser= MzXML_Parser.MRM_mzXML_Parser( item, self.time_cycle )
			
			#self.connect( parser, QtCore.SIGNAL("update_pb"), self.emission)
			self.emit(QtCore.SIGNAL("status_message"), " ".join(["Parsing", item.getXmlFile(), "..."])) 
			parser.parsing(self.time_cycle)
			#sent spl
			QtGui.QApplication.processEvents()
			#update the model
			#solution emit the object parser then build models
			parser.build_models(self.chrom_model, self.spectr_model)
			#self.emit(QtCore.SIGNAL("sent_spl"), parser.getSpl())
			#self.emit(QtCore.SIGNAL("models"), self.chrom_model, self.spectr_model)*********
			
	def begin(self):
		self.start()
		self.exec_()
	
	



class visualisation_controller(dial):
	"""Visualisation Controller"""
	
	def __init__(self, lspl, visu):
		dial.__init__(lspl, visu)
		self.lxml = True
		try:
			from lxml import etree
		except ImportError:
			self.visu.lxml = False
			
		self.run_time =None	
		
		#connection
		QtCore.QObject.connect( self.visu.pushButton_3, QtCore.SIGNAL ( "clicked()" ), self.load_file)
		QtCore.QObject.connect( self.visu.pushButton_4, QtCore.SIGNAL ( "clicked()" ), self.merging_files)
		QtCore.QObject.connect( self.visu.pushButton_5, QtCore.SIGNAL ( "clicked()" ), self.merging_peaks)
		QtCore.QObject.connect( self.visu.button, QtCore.SIGNAL ( "clicked()" ), self.dialog)
		QtCore.QObject.connect( self.visu.pushButton_6, QtCore.SIGNAL ( "clicked()" ), self.estimate_runtime)

		

	
	def load_file(self):
		"""initialize file and time_cycle each time parsing button is pressed"""
		
		files = str(self.visu.lineEdit.text()).split(';')
		time_cycle = float(self.visu.lineEdit_2.text())
		self.visu.close()
		
		lspl = obj.ListSample()
		for file in files:
			if file not in self.lspl.getFiles():
				spl =obj.Sample(file)
				self.lspl.append(spl)
				lspl.append(spl)
			else:
				self.visu.parent.ShowWarningMessage("Error name of file", "One name of file already exist in our data, it will be ignored")
		self.visu.parent.ShowInStatusBar("Parsing, can take few seconds, please wait...", 10000)
		
		thread = Parsing_thread(lspl, self.lxml, time_cycle, self.visu.parent.chrom_model, self.visu.parent.spectr_model, self.visu.parent)
		QtCore.QObject.connect(thread, QtCore.SIGNAL ( "update_pb" ), self.visu.parent.update_progress_bar)
		QtCore.QObject.connect(thread, QtCore.SIGNAL ( "started()" ), self.visu.parent.to_indetermined_mode)
		QtCore.QObject.connect(thread, QtCore.SIGNAL ( "sent_spl" ), self.add_spl)
		QtCore.QObject.connect(thread, QtCore.SIGNAL ( "status_message"), self.visu.parent.ShowInStatusBar)
		QtCore.QObject.connect(thread, QtCore.SIGNAL ( "finished()" ), self.visu.parent.to_determined_mode)
		QtCore.QObject.connect(thread, QtCore.SIGNAL ( "finished()" ), self.setModels)
		#QtCore.QObject.connect(thread, QtCore.SIGNAL ( "models" ), self.setModels)
		thread.begin()
	
	def setModels(self):
		self.visu.parent.treeView.setModel(self.visu.parent.chrom_model)
		
	def add_spl(self, spl):
		self.lspl.Append(spl)
		self.visu.parent.ShowInformationMessage("Parsing done",  spl.getXmlFile().join(["Parsing of -","- has been done succesfully"]))
		
	
	def merging_files(self):
		"""merge different file"""
		
		files = str(self.visu.lineEdit_3.text()).split(";")
		name = str(self.visu.lineEdit_4.text())
		self.visu.close()
		lspl =obj.ListSample()
		for f in files:
			lspl.append(self.lspl.Sample(f))
		
		spectr =proc.Merging_Spectra(lspl)
		new_sample =obj.Sample(name, spectra= spectr)
		self.lspl.append(new_sample)
		root_chrom = QtGui.QStandardItem(new_sample.getXmlFile())
		root_spectra = QtGui.QStandardItem(new_sample.getXmlFile())
		for spectr in new_sample.getSpectra():
			root_spectra.appendRow(QtGui.QStandardItem(str(spectr.t_min)))
		self.visu.parent.spectr_model.appendRow(root_spectra)
		self.visu.parent.chrom_model.appendRow(root_chrom)
		self.visu.parent.treeView.setModel(self.visu.parent.chrom_model)
	
	
	def merging_peaks(self):
		"""merge peaks"""
		files = str(self.visu.lineEdit_3.text()).split(";")
		name = str(self.visu.lineEdit_4.text())
		self.visu.close()
		"""
		for f in files:
			if not self.lspl.Sample(f).get_peak_list():
				print ("error one file does not have any peaks")
				return
		"""		
		lspl =obj.ListSample()
		for f in files:
			lspl.append(self.lspl.Sample(f))
		# make a new containing peaks
		
		pkl = proc.Merging_Peaks(lspl)
		new_sample =obj.Sample(name, peaks= pkl)
		self.lspl.append(new_sample)
		root = QtGui.QStandardItem(new_sample.getXmlFile())

		for peak in new_sample.get_peak_list():
			root.appendRow(QtGui.QStandardItem(str(peak.get_trans_prec())+" "+ str(peak.get_rt())))
		self.visu.parent.peak_model.appendRow(root)
		self.visu.parent.treeView_2.setModel(self.visu.parent.peak_model)


	def run_time(self, runtime):
		self.run_time =run_time

	def estimate_runtime(self):
		"""
		estimate the time of one scan if user does not get it
		"""
		#<precursorMz precursorIntensity="0" >97</precursorMz>
		#retentionTime="PT0.0101S"
		prec = re.compile('\s+<precursorMz precursorIntensity="\d+" >(\d+)</precursorMz>\n')
		rt = re.compile('\s+retentionTime="PT(.+)S"\n')
		
		#first get information
		
		files = str(self.visu.lineEdit.text()).split(';')
		#if not files:
		#	self.visu.parent.ShowErrorMessage("Tragic Error", "The previous field must be non-empty")
		
		for file in files:
			with open(file) as f:
				line = f.readline();i=1
				#getting the first rt and the first prec
				while rt.match(line) is None:
					line =f.readline();i+=1
				rt_0 = rt.match(line).group(1)
				while prec.match(line) is None:
					line =f.readline();i+=1
				prec_0 = float(prec.match(line).group(1))
				#done
				#getting next while new prec < prec_0
				next_prec = 1000.; new_rt =0.
				while next_prec >= prec_0 :
					while rt.match(line) is None:
						line =f.readline();i+=1
					new_rt = rt.match(line).group(1)
					while prec.match(line) is None:
						line =f.readline();i+=1
					next_prec = float(prec.match(line).group(1))
				#emission
				self.visu.lineEdit_2.setText(str(abs(float(rt_0) -float(new_rt))))
				

if __name__=="__main__":
	app = QtGui.QApplication(sys.argv)
	visu=visualisation_controller()
	visu.tabwidget.show()
	app.exec_()

